/*
 *    Copyright (c) 2018-2025, proj All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the proj developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: proj
 */
package com.ykht.proj.coupon.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.codingapi.tx.annotation.TxTransaction;
import com.ykht.proj.activity.api.feign.RemoteActivityShopService;
import com.ykht.proj.activity.entity.CnActivity;
import com.ykht.proj.activity.vo.CardShopDto;
import com.ykht.proj.activity.vo.CnDiscountShopVoReq;
import com.ykht.proj.activity.vo.CnGroupShopVoReq;
import com.ykht.proj.admin.api.Enum.UserRoleTypeEnum;
import com.ykht.proj.admin.api.dto.UserDTO;
import com.ykht.proj.admin.api.entity.SysUser;
import com.ykht.proj.admin.api.feign.RemoteUserService;
import com.ykht.proj.common.core.constant.CommonConstants;
import com.ykht.proj.common.core.util.DistanceUtil;
import com.ykht.proj.common.core.util.R;
import com.ykht.proj.common.security.util.SecurityUtils;
import com.ykht.proj.comsrv.api.feign.RemoteAreaService;
import com.ykht.proj.comsrv.entity.CnArea;
import com.ykht.proj.coupon.Enum.CouponEnum;
import com.ykht.proj.coupon.Enum.UserTypeEnum;
import com.ykht.proj.coupon.dto.SearchDto;
import com.ykht.proj.coupon.entity.*;
import com.ykht.proj.coupon.mapper.*;
import com.ykht.proj.coupon.service.*;
import com.ykht.proj.coupon.vo.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 店铺表
 *
 * @author proj code generator
 * @date 2020-11-18 17:10:45
 */
@Service
@RequiredArgsConstructor
@Slf4j
@Transactional
public class CnShopServiceImpl extends ServiceImpl<CnShopMapper, CnShop> implements CnShopService {

	private final CnShopMapper cnShopMapper;
	private final CnCouShopMapper cnCouShopMapper;
	private final CnCouShopService cnCouShopService;
	private final CnCollectionMapper cnCollectionMapper;
	private final CnCouponService cnCouponService;
	private final CnBraLabService cnBraLabService;
	private final CnCouponLogMapper cnCouponLogMapper;
	private final CnBrandService cnBrandService;
	private final RemoteUserService remoteUserService;
	private final RemoteActivityShopService remoteActivityShopService;
	private final RemoteAreaService remoteAreaService;

	/**
	 * 根据角色类型 获取后台的门店列表 分页查询
	 *
	 * @param page
	 * @param shopVo
	 * @return
	 */
	@Override
	public R findPage(Page page, CnShopVo shopVo) {
		Integer userType = SecurityUtils.getUser().getUserType();
		Long sjId = SecurityUtils.getSjId();
		Long userId = SecurityUtils.getUserId();
		if (userType.equals(UserTypeEnum.company.getValue())) {
			shopVo.setCompanyId(sjId);
		}
		if (userType.equals(UserTypeEnum.brand.getValue())) {
			shopVo.setBrandId(sjId);
		}
		if (userType.equals(UserTypeEnum.shop.getValue())) {
			shopVo.setLoginId(userId);
		}
		List<CnShopVo> list = cnShopMapper.findPage(page, shopVo);
		if (list != null && list.size() > 0) {
			List<Long> loginList = list.stream().map(CnShopVo::getLoginId).collect(Collectors.toList());
			List<SysUser> userList = remoteUserService.userByIds(loginList);
			for (CnShopVo cnShopVo : list) {
				JSONObject json = new JSONObject();
				json.putOpt("formattedAddress", cnShopVo.getAddress());
				JSONObject json2 = new JSONObject();
				json2.putOpt("lat", cnShopVo.getLatitude());
				json2.putOpt("lng", cnShopVo.getLongitude());
				json.putOpt("location", json2);
				cnShopVo.setMap(json);
				userList.stream().forEach(user -> {
					if (Long.valueOf(user.getUserId()).equals(cnShopVo.getLoginId())) {
						cnShopVo.setUsername(user.getUsername());
						cnShopVo.setLoginName(user.getUsername());
					}
				});
			}
		}
		return R.ok(page.setRecords(list));
	}

	@Override
	public AboutShopVo aboutShop(AboutShopReq aboutShopReq) {
		return cnShopMapper.aboutShop(aboutShopReq);
	}

	@Override
	public List<SearchResp> search(SearchReq searchReq) {

		List<SearchDto> list = cnShopMapper.search(searchReq);
		List<SearchResp> respList = new ArrayList<>();
		SearchResp resp = new SearchResp();
		/**
		 * 组装数据结构
		 */
		for (SearchDto o : list) {
			if (o.getFlag() == 1) continue;
			if (!o.getBrandId().equals(resp.getBrandId())) {
				resp = new SearchResp();
				resp.setBrandId(o.getBrandId());
				resp.setBrandName(o.getBrandName());
				resp.setFlag(o.getFlag());
				resp.setCreateTime4First(o.getCreateTime());
				resp.setDistance4First(o.getDistance());
				respList.add(resp);
			}
			SearchResp.SimpleShop shop = new SearchResp.SimpleShop();
			BeanUtil.copyProperties(o, shop);
			shop.setDistance(o.getDistance());
			shop.setCreateTime(o.getCreateTime());
			resp.getShopList().add(shop);

		}
		//过滤掉不显示的
		respList = (StringUtils.isBlank(searchReq.getLatitude())
				? respList.stream().sorted(Comparator.comparing(SearchResp::getFlag).reversed().thenComparing(SearchResp::getCreateTime4First).reversed())//创建时间降序
				: respList.stream().sorted(Comparator.comparing(SearchResp::getDistance4First).thenComparingInt(SearchResp::getFlag)))//距离升序
				.collect(Collectors.toList());
		log.info(JSONUtil.toJsonStr(respList));

		return respList;
	}

	/**
	 * 根据品牌和门店
	 * 有定位就由远及近
	 * 没有定位就创建时间
	 *
	 * @param page
	 * @param req
	 * @return
	 */
	@Override
	public IPage<AboutShopVo> aboutShopList(Page page, AboutShopReq req) {
		req.setDisplay(0);
		IPage<AboutShopVo> resp = cnShopMapper.aboutShopList(page, req);
		Set brandIdSet = new HashSet();
		Set shopIdSet = new HashSet();
		resp.getRecords().stream().forEach(o -> {
			brandIdSet.add(o.getBrandId());
			shopIdSet.add(o.getShopId());
		});

		List<ShopHasCouponCount> shopHasCouponCounts = cnCouponService.shopHasCouponCount(shopIdSet);
		Map<Long, Integer> map = shopHasCouponCounts.stream().collect(Collectors.toMap(ShopHasCouponCount::getShopId, ShopHasCouponCount::getCount));

		Map<Long, Integer> fxConfBrandPersonMap = new FxConfBrandPerson().selectList(Wrappers.lambdaQuery(FxConfBrandPerson.class).eq(FxConfBrandPerson::getSwitchs, 0).in(FxConfBrandPerson::getBrandId, brandIdSet))
				.stream().collect(Collectors.toMap(FxConfBrandPerson::getBrandId, FxConfBrandPerson::getSwitchs));
		resp.getRecords().stream().forEach(o->{
			o.setCouponCount(map.getOrDefault(o.getShopId(),0).intValue() + o.getTyCouponCount());
			o.setFxFlag(fxConfBrandPersonMap.get(o.getBrandId()) != null ? 1 : 0);
		});
		return resp;
	}

	/**
	 * 根据品牌和门店
	 * 有定位就由远及近
	 * 没有定位就优惠券的多的在前
	 *
	 * @param page
	 * @param req
	 * @return
	 */
	@Override
	public IPage<AboutShopVo> aboutMaxCouponShopList(Page page, AboutShopReq req) {
		req.setDisplay(0);
		IPage<AboutShopVo> resp = cnShopMapper.aboutMaxCouponShopList(page, req);
		List<Long> ids = resp.getRecords().stream().map(AboutShopVo::getShopId).collect(Collectors.toList());
		if (ids.size() == 0) return resp;
		req.setIds(ids);
		List<AboutShopVo> aboutShopList = this.shopByIds(req);
		resp.setRecords(aboutShopList);
		return resp;
	}

	/**
	 * 门店ids获取门店详情
	 *
	 * @param req
	 * @return
	 */
	@Override
	public List<AboutShopVo> shopByIds(AboutShopReq req) {
		List<AboutShopVo> list = cnShopMapper.aboutShopList(req);
		List<Long> ids = list.stream().map(AboutShopVo::getShopId).collect(Collectors.toList());
		if (list.size() == 0) return list;
		List<CnCouShop> temp = cnCouShopMapper.selectList(Wrappers.lambdaQuery(CnCouShop.class).in(CnCouShop::getShopId, ids));
		list.stream().forEach(o -> {
			long size = temp.stream().filter(oo -> o.getShopId().equals(oo.getShopId())).count();
			o.setCouponCount((int) size + o.getTyCouponCount());
		});
		//上面的list不能够确定就是降序排序
		return list.stream().sorted(Comparator.comparing(AboutShopVo::getCouponCount).reversed()).collect(Collectors.toList());
	}

	@Override
	public List<CnShop> listByVoMap(Map<String, Object> map) {
		return cnShopMapper.listByVoMap(map);
	}

	@Override
	public CnShopVo getDetailById(Long id) {
		return cnShopMapper.getDetailById(id);
	}

	/**
	 * 根据优惠券
	 *
	 * @param page
	 * @param req
	 * @return
	 */
	@Override
	public IPage<AboutShopVo> pageByCoupon(Page page, AboutShopByCouponReq req) {
		CnCoupon cnCoupon = cnCouponService.getById(req.getCouponId());
		if (CouponEnum.currency.getValue().equals(cnCoupon.getType())) {//通用券通过品牌查询
			AboutShopReq aboutShopReq = new AboutShopReq();
			aboutShopReq.setLatitude(req.getLatitude());
			aboutShopReq.setLongitude(req.getLongitude());
			aboutShopReq.setBrandId(cnCoupon.getBrandId());
			IPage<AboutShopVo> resp = this.aboutShopList(page, aboutShopReq);
			return resp;
		} else {
			IPage<AboutShopVo> resp = cnShopMapper.pageByCoupon(page, req);
			resp.getRecords().stream().forEach(o -> {
				List temp = cnCouShopMapper.selectList(Wrappers.lambdaQuery(CnCouShop.class).eq(CnCouShop::getShopId, o.getShopId()));
				o.setCouponCount(temp.size() + o.getTyCouponCount());
			});
			return resp;
		}

	}

	@Override
	public PpgAndShopsResp ppgAndShops(Page page, PpgAndShopsReq req) {
		PpgAndShopsResp resp = new PpgAndShopsResp();
		resp.setPpg(cnBrandService.pinPaiGuan(req.getBrandId()));
		AboutShopReq aboutShopReq = new AboutShopReq();
		aboutShopReq.setBrandId(req.getBrandId());
		aboutShopReq.setLatitude(req.getLatitude());
		aboutShopReq.setLongitude(req.getLongitude());
		resp.setShops(this.aboutShopList(page, aboutShopReq));
		return resp;
	}

	@Override
	public List<CnShopDisVo> shopAndDistant(CnShopDisVo cnShopDisVo) {
		return cnShopMapper.shopAndDistant(cnShopDisVo);
	}

	@Override
	public List<CnShopDisVo> shopAndDistant4NotTyCoupon(String latitude, String longitude, Long couponId) {
		return cnShopMapper.shopAndDistant4NotTyCoupon(latitude, longitude, couponId);
	}

	/*public static void main(String[] args) {
		List<CnCouponReceiveVo> list = new ArrayList<>();
		CnCouponReceiveVo temp = new CnCouponReceiveVo();
		CnCouponReceiveVo temp1 = new CnCouponReceiveVo();
		CnCouponReceiveVo temp2 = new CnCouponReceiveVo();
		CnCouponReceiveVo temp3= new CnCouponReceiveVo();
		CnCouponReceiveVo temp4= new CnCouponReceiveVo();
		temp.setCreateTime(LocalDateTime.now().plusDays(1));
		temp.setUseFlag(0);
		temp.setId(2l);
		temp1.setCreateTime(LocalDateTime.now().plusDays(2));
		temp1.setUseFlag(0);
		temp1.setId(1l);
		temp2.setCreateTime(LocalDateTime.now());
		temp2.setUseFlag(1);
		temp2.setId(0l);
		temp4.setCreateTime(LocalDateTime.now().plusDays(1));
		temp4.setUseFlag(1);
		temp4.setId(0l);
		temp3.setCreateTime(LocalDateTime.now());
		temp3.setUseFlag(0);
		temp3.setId(3l);
		list.add(temp);
		list.add(temp3);
		list.add(temp2);
		list.add(temp1);
		list.add(temp4);

//		System.out.println(JSONUtil.toJsonStr(list));

//		List<CnCouponReceiveVo> slist = list.stream().sorted().collect(Collectors.toList());
//		List<CnCouponReceiveVo> slist = list.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
//		list = list.stream().sorted(Comparator.comparing(CnCouponReceiveVo::getCreateTime).reversed().thenComparing(CnCouponReceiveVo::getUseFlag)).collect(Collectors.toList());
//		list = list.stream().sorted(Comparator.comparing(CnCouponReceiveVo::getUseFlag).thenComparing(CnCouponReceiveVo::getCreateTime).reversed()).collect(Collectors.toList());
//		list = list.stream().sorted(Comparator.comparing(CnCouponReceiveVo::getCreateTime).thenComparing(CnCouponReceiveVo::getUseFlag)).collect(Collectors.toList());
//		list = list.stream().sorted(Comparator
//				.comparing(CnCouponReceiveVo::getUseFlag).reversed()
//				.thenComparing(CnCouponReceiveVo::getCreateTime).reversed())
//				.collect(Collectors.toList());
		list.forEach(e -> System.out.println("Id:"+ e.getId()+", UseFlag:"+e.getUseFlag()+", CreateTime: "+e.getCreateTime()));
//		Map<Long,List<CnCouponReceiveVo>> map = list.stream().collect(Collectors.groupingBy(CnCouponReceiveVo::getId));
//		System.out.println(JSONUtil.toJsonStr(map));

	}*/

	private final FxConfBrandPersonService fxConfBrandPersonService;
	@Override
	public ShopDetail getShopDetail(Long id,BaseLonLat baseLonLat) {

		Long loginId = SecurityUtils.getPersonId();
		ShopDetail shopDetail = new ShopDetail();
		//查看该门店是否被收藏
		CnCollection cnCollection = cnCollectionMapper.selectOne(Wrappers.lambdaQuery(CnCollection.class)
				.eq(CnCollection::getPerId, loginId).eq(CnCollection::getShopId, id));
		shopDetail.setCollFlag(cnCollection == null ? "1" : "0");
		//查看该门店参与的活动列表
		R<List<CnActivity>> r = remoteActivityShopService.actByShopId(id);
		if (CommonConstants.SUCCESS == r.getCode()) shopDetail.setActList(r.getData());

		CnShop shop = new CnShop().selectById(id);
		shopDetail.setCnShop(shop);
		//分销“赚”字
		shopDetail.setFxFlag(fxConfBrandPersonService.fxFlag(shop.getBrandId()));

		if (baseLonLat.getLatitude()!=null){
			Long distance = DistanceUtil.getDistanceMeter2Long(baseLonLat,shop);
//			Long distance = cnShopMapper.distanceByLonLat(baseLonLat,new BaseLonLat(shop.getLongitude(),shop.getLatitude()));
			shopDetail.setDistance(distance);
		}
		CnBrand brand = new CnBrand().selectById(shop.getBrandId());
		shopDetail.setCnBrand(brand);
		List<CnCouponReceiveVo> couponList = cnCouponService.couponListByShopIdAndBrandId(id, shop.getBrandId());
		//我领取的券
		List<Long> logList = cnCouponLogMapper.selectList(Wrappers.lambdaQuery(CnCouponLog.class)
				.eq(CnCouponLog::getRecipientId, SecurityUtils.getPersonId())
				.eq(CnCouponLog::getStatus, 0))//待使用
				.stream().map(CnCouponLog::getCouponId).collect(Collectors.toList());
		couponList.stream().forEach(o -> o.setUseFlag(logList.contains(o.getId()) ? 1 : 0));

		/**  排序  此处过采坑
		 *
		 * //先根据状态升序排序
		 * //根据时间降序排序
		 */
		couponList = couponList.stream()
				.sorted(Comparator.comparing(CnCouponReceiveVo::getUseFlag).reversed()
						.thenComparing(CnCouponReceiveVo::getCreateTime).reversed())
				.collect(Collectors.toList());

		shopDetail.setCouponList(couponList);
		List<CnBrand> brandList = cnBraLabService.getBrand4ContainLabel(brand.getId());
		List<Long> brandIds = brandList.stream().map(CnBrand::getId).collect(Collectors.toList());

		//品牌下的所有可用最大通用券
		List<CnCoupon> tyCouponList = new ArrayList<>();
		//品牌下的所有可用通用券
		cnCouponService.list(Wrappers.lambdaQuery(CnCoupon.class).in(CnCoupon::getBrandId, brandIds)
				.eq(CnCoupon::getType, 0)//通用券
				.eq(CnCoupon::getStatus, 0))//上架
				.stream().filter(o -> logList.contains(o.getId()) != true).collect(Collectors.groupingBy(CnCoupon::getBrandId))
				.forEach((k, v) -> {
					tyCouponList.add(v.stream().sorted(Comparator.comparing(CnCoupon::getReductionMoney).reversed()).collect(Collectors.toList()).get(0));
				});

		List<Long> couShopList = cnCouShopMapper.selectList(Wrappers.lambdaQuery(CnCouShop.class)
				.eq(CnCouShop::getShopId, shop.getId())).stream().map(CnCouShop::getCouId).collect(Collectors.toList());
		//品牌下所有的 未领取的 非自己门店的 门店券
		List<RecommendCouponVo> tempRecommendCouponList = cnCouponService.recommendCouponList(brandList, shop)
				.stream().filter(o -> (logList.contains(o.getId()) != true) && (couShopList.contains(o.getId()) != true)).collect(Collectors.toList());

		//根据门店分组
		Map<Long, List<RecommendCouponVo>> map = tempRecommendCouponList.stream().collect(Collectors.groupingBy(RecommendCouponVo::getShopId));
		List<RecommendCouponVo> recommend = new ArrayList<>();
		//遍历map ，每个门店取一个最大的优惠券，然后和tyCouponList里同品牌的券比较，取最大，活的最终优惠券
		map.forEach((k, v) -> {
			RecommendCouponVo vo = v.stream().sorted(Comparator.comparing(RecommendCouponVo::getReductionMoney).reversed()).collect(Collectors.toList()).get(0);
			//比较同品牌下通用券和最大门店券的大小，获胜者被翻牌
			tyCouponList.stream().filter(o -> (o.getBrandId().equals(vo.getBrandId())) && (o.getReductionMoney().compareTo(vo.getReductionMoney()) == 1)).forEach(o -> BeanUtil.copyProperties(o, vo));
			recommend.add(vo);
		});

		List<RecommendCouponVo> finalRCList = recommend.stream().sorted(Comparator.comparing(RecommendCouponVo::getDistance)).collect(Collectors.toList());
		shopDetail.setRecommendCouponList(finalRCList.size() >= 6 ? finalRCList.subList(0, 6) : finalRCList);
		shopDetail.getRecommendCouponList().stream().forEach(oo -> {
			List<CnShopSimpleVo> simpleVoList = cnCouShopService.findShop4CouponListByCouponId(oo.getId());
			oo.setShopSimpleVo(simpleVoList);
		});
		//足迹
		CnPerson cnPerson = new CnPerson();
		cnPerson.setId(loginId);
		cnPerson = cnPerson.selectById();
		if (null != cnPerson.getPhone()) {

			CnFootPrint temp = cnFootPrintMapper.selectOne(Wrappers.lambdaQuery(CnFootPrint.class)
					.eq(CnFootPrint::getType, 1).eq(CnFootPrint::getPerId, loginId).eq(CnFootPrint::getTatId, id));
			if (temp == null) {
				CnFootPrint cnFootPrint = new CnFootPrint();
				cnFootPrint.setType(1);
				cnFootPrint.setPerId(loginId);
				cnFootPrint.setTatId(id);
				cnFootPrint.setCreateTime(LocalDateTime.now());
				cnFootPrint.setCreateUser(loginId);
//					cnFootPrintMapper.insert(cnFootPrint);
				cnFootPrintMapper.replaceInto(cnFootPrint);
			} else {
				temp.setUpdateTime(LocalDateTime.now());
				temp.setUpdateUser(loginId);
				cnFootPrintMapper.updateById(temp);
			}
		}

		return shopDetail;
	}

	private final CnFootPrintMapper cnFootPrintMapper;

	/**
	 * C端（用户） 首页  爆款优惠
	 *
	 * @param longitude 经度
	 * @param latitude  纬度
	 * @param userId    登录人ID
	 * @return
	 */
	@Override
	public List<CnCouponDetailResp> getHotCouponList(String longitude, String latitude, Long userId) {
		return cnShopMapper.getHotCouponList(longitude, latitude, userId);
	}

	/**
	 * 获取通用的优惠券
	 *
	 * @param longitude
	 * @param latitude
	 * @param userId
	 * @return
	 */
	@Override
	public List<CnCouponDetailResp> getCommonCouponList(String longitude, String latitude, Long userId, List<Long> ids) {
		return cnShopMapper.getCommonCouponList(longitude, latitude, userId, ids);
	}

	/**
	 * 获取多门店的优惠券
	 *
	 * @param longitude
	 * @param latitude
	 * @param userId
	 * @return
	 */
	@Override
	public List<CnCouponDetailResp> getMultiStoreCouponList(String longitude, String latitude, Long userId, List<Long> ids) {
		return cnShopMapper.getMultiStoreCouponList(longitude, latitude, userId, ids);
	}

	/**
	 * 获取单个门店的优惠券
	 *
	 * @param longitude
	 * @param latitude
	 * @param userId
	 * @return
	 */
	@Override
	public List<CnCouponDetailResp> getSingleStoreCouponList(String longitude, String latitude, Long userId, List<Long> ids) {
		return cnShopMapper.getSingleStoreCouponList(longitude, latitude, userId, ids);
	}

	/**
	 * 获取创建活动的门店
	 *
	 * @param labelId 标签ID
	 * @param name    门店名称
	 * @return
	 */
	@Override
	public List<CnShop> getActivityShop(Long labelId, String name) {
		return cnShopMapper.getActivityShop(labelId, name);
	}


	/**
	 * 新增店铺表
	 *
	 * @param cnShopVo
	 * @return
	 */
	@TxTransaction(isStart = true) // 请求方 要加 isStart = true  被请求的不用加  isStart = true  控制事物 注解
	@Transactional(rollbackFor = Exception.class)
	@Override
	public R saveAndUser(CnShopVo cnShopVo) throws Exception {
		CnShop shop = new CnShop().selectOne(Wrappers.lambdaQuery(CnShop.class)
				.eq(CnShop::getName, cnShopVo.getName()));
		if (shop != null) {
			return R.ok("门店名称已经存在");
		}
		if (cnShopVo.getDisplay().equals(0)) {
			if (cnShopVo.getContractStartTime().isAfter(LocalDateTime.now()) || cnShopVo.getContractEndTime().isBefore(LocalDateTime.now())) {
				return R.failed("当前时间不在该门店合作时间内，不能上架");
			}
			cnShopVo.setOnTime(LocalDateTime.now());
		} else {
			cnShopVo.setOffTime(LocalDateTime.now());
		}
		if (null != cnShopVo.getAreaId()){
			CnArea areaId = remoteAreaService.getByAreaId(cnShopVo.getAreaId());
			cnShopVo.setAreaName(areaId.getName());
		}
		if (null != cnShopVo.getCityId()){
			CnArea cityId = remoteAreaService.getByAreaId(cnShopVo.getCityId());
			cnShopVo.setCityName(cityId.getName());
		}
		if (null != cnShopVo.getProvinceId()){
			CnArea provinceId = remoteAreaService.getByAreaId(cnShopVo.getProvinceId());
			cnShopVo.setProvinceName(provinceId.getName());
		}

		cnShopVo.setCreateTime(LocalDateTime.now());
		cnShopVo.setCreateUser(SecurityUtils.getUserId());
		cnShopVo.setUserType(UserTypeEnum.shop.getValue());
		CnShop cnShop = BeanUtil.toBean(cnShopVo, CnShop.class);
		cnShopMapper.insert(cnShop);
		cnShopVo.setId(cnShop.getId());
		if (cnShop.getLoginId() != null) {
			SysUser user = new SysUser();
			user.setUserId(Integer.parseInt(cnShop.getLoginId().toString()));
			user.setSjIdDefLogin(cnShop.getId());
			R bindSj = remoteUserService.bindSj(user);
		}

		if (cnShop.getLoginId() == null) {
			UserDTO userDTO = new UserDTO();
			userDTO.setUsername(StringUtils.isEmpty(cnShopVo.getUsername()) ? cnShopVo.getName() : cnShopVo.getUsername());
			userDTO.setUserType(UserTypeEnum.shop.getValue());
			userDTO.setPassword("123456");
			userDTO.setParentId(cnShopVo.getParentId());
			userDTO.setRole(UserRoleTypeEnum.shop.getValue());
			userDTO.setSjIdDefLogin(cnShop.getId());
			R<UserDTO> userDTOR = remoteUserService.saveUser(userDTO);
			if (userDTOR.getCode() != 0) {
				throw new RuntimeException(userDTOR.getMsg());
			}
			cnShop.setLoginId(Long.valueOf(userDTOR.getData().getUserId()));
			this.updateById(cnShop);
		}
		return R.ok(cnShopVo);
	}

	/**
	 * 修改门店
	 *
	 * @param cnShopVo
	 * @return
	 */
	@TxTransaction(isStart = true) // 请求方 要加 isStart = true  被请求的不用加  isStart = true  控制事物 注解
	@Transactional(rollbackFor = Exception.class)
	@Override
	public R updateAndUser(CnShopVo cnShopVo) throws Exception {
		CnShop shop = new CnShop().selectOne(Wrappers.lambdaQuery(CnShop.class)
				.eq(CnShop::getName, cnShopVo.getName())
				.ne(CnShop::getId, cnShopVo.getId()));
		if (shop != null) {
			return R.ok("门店名称已经存在");
		}
		if (null != cnShopVo.getAreaId()){
			CnArea areaId = remoteAreaService.getByAreaId(cnShopVo.getAreaId());
			cnShopVo.setAreaName(areaId.getName());
		}
		if (null != cnShopVo.getCityId()){
			CnArea cityId = remoteAreaService.getByAreaId(cnShopVo.getCityId());
			cnShopVo.setCityName(cityId.getName());
		}
		if (null != cnShopVo.getProvinceId()){
			CnArea provinceId = remoteAreaService.getByAreaId(cnShopVo.getProvinceId());
			cnShopVo.setProvinceName(provinceId.getName());
		}
		cnShopVo.setUpdateTime(LocalDateTime.now());
		cnShopVo.setUpdateUser(SecurityUtils.getUserId());
		cnShopVo.setUserType(UserTypeEnum.shop.getValue());
		if (cnShopVo.getLoginId() != null) {
			SysUser user = new SysUser();
			user.setUserId(Integer.parseInt(cnShopVo.getLoginId().toString()));
			user.setSjIdDefLogin(cnShopVo.getId());
			remoteUserService.bindSj(user);
		}

		if (null != cnShopVo.getUsername()) {
			UserDTO userDTO = new UserDTO();
			userDTO.setUsername(cnShopVo.getUsername());
			userDTO.setUserType(UserTypeEnum.shop.getValue());
			userDTO.setPassword("123456");
			userDTO.setParentId(cnShopVo.getParentId());
			userDTO.setRole(UserRoleTypeEnum.shop.getValue());
			userDTO.setSjIdDefLogin(cnShopVo.getId());
			R<UserDTO> userDTOR = remoteUserService.saveUser(userDTO);
			if (userDTOR.getCode() != 0) {
				throw new RuntimeException(userDTOR.getMsg());
			}
			cnShopVo.setLoginId(Long.valueOf(userDTOR.getData().getUserId()));
		}
		CnShop cnShop = BeanUtil.toBean(cnShopVo, CnShop.class);
		this.updateById(cnShop);
		return R.ok(cnShopVo);
	}

	/**
	 * 门店上下架
	 *
	 * @param cnShopVo 门店表
	 * @return
	 */
	@Override
	public R updateByDisplay(CnShopVo cnShopVo) throws Exception {
		cnShopVo.setUpdateUser(SecurityUtils.getUserId());
		cnShopVo.setUpdateTime(LocalDateTime.now());
		CnShop cnShop = BeanUtil.toBean(cnShopVo, CnShop.class);
		// 上架
		if (cnShopVo.getDisplay().equals(0)) {
			CnShop shop = this.getById(cnShopVo.getId());
			if (shop.getContractStartTime().isAfter(LocalDateTime.now()) || shop.getContractEndTime().isBefore(LocalDateTime.now())) {
				return R.failed("当前时间不在该门店合作时间内，不能上架");
			}
			cnShop.setOnTime(LocalDateTime.now());
			return R.ok(this.updateById(cnShop));
			// 下架
		} else {
			cnShop.setOffTime(LocalDateTime.now());

			return R.ok();
		}
	}

	/**
	 * 创建群组取门店列表（根据品牌标签, 品牌/门店名, 地址查询,协议类型)
	 *
	 * @param cnGroupShopVoReq
	 * @return
	 */
	@Override
	public List<CnGroupShopVoReq> getByGroup(CnGroupShopVoReq cnGroupShopVoReq) {
		return cnShopMapper.getByGroup(cnGroupShopVoReq);
	}

	@Override
	public List<CnShopDisVo> distanceList(ShopDisListVo shopDisListVo) {
		List<CnShop> list = this.list(Wrappers.lambdaQuery(CnShop.class).in(shopDisListVo.getIds()!=null && shopDisListVo.getIds().size()>0,CnShop::getId,shopDisListVo.getIds()));

		List<CnShopDisVo> disVoList = new ArrayList<>();
		Set brandSet = new HashSet();
		list.stream().forEach(o->{
			CnShopDisVo temp = BeanUtil.toBean(o,CnShopDisVo.class);
			if (BeanUtil.isNotEmpty(shopDisListVo.getLonLat())){
				temp.setDistance(DistanceUtil.getDistanceMeter2Long(o,shopDisListVo.getLonLat()));
			}
			disVoList.add(temp);
			brandSet.add(o.getBrandId());
		});
		//获取品牌便签详情
		List<CnBrandLabel> brandLabelList = cnBrandService.brandAndLabelByIds(ListUtil.toList(brandSet));
//		Map<Long,CnBrandLabel> map = brandLabelList.stream().collect(Collectors.toMap(CnBrandLabel::getBrandId, Function.identity()));
		Map<Long,CnBrandLabel> map = brandLabelList.stream().collect(Collectors.toMap(CnBrandLabel::getBrandId, Function.identity(), (key1, key2) -> key2));
		List<CnShopDisVo> tempList = disVoList.stream().map(o->{
			o.setBrandLabel(map.getOrDefault(o.getBrandId(),new CnBrandLabel()));
			return o;
		}).collect(Collectors.toList());
		if (BeanUtil.isNotEmpty(shopDisListVo.getLonLat())){
			tempList = tempList.stream().sorted(Comparator.comparing(CnShopDisVo::getDistance)).collect(Collectors.toList());
		}
		return tempList;
	}

	/**
	 * 获取卡能使用门店列表 （根据品牌标签, 品牌/门店名, 地址查询赛选）
	 *
	 * @param cardShopDto
	 * @return
	 */
	@Override
	public List<CardShopDto> getByInfoShop(CardShopDto cardShopDto) {
		return cnShopMapper.getByInfoShop(cardShopDto);
	}

	/**
	 * 根据门店ID获取全部门店信息
	 *
	 * @param shopId
	 * @return
	 */
	@Override
	public CnShopVo getByShopId(Long shopId) {
		return cnShopMapper.getByShopId(shopId);
	}

	/**
	 * 创建优惠方案获取门店列表（根据品牌id, 门店名, 地址查询)
	 *
	 * @param page
	 * @param cnDiscountShopVoReq
	 * @return
	 */
	@Override
	public IPage<CnDiscountShopVoReq> getByDiscountPlan(Page page, CnDiscountShopVoReq cnDiscountShopVoReq) {
		return cnShopMapper.getByDiscountPlan(page, cnDiscountShopVoReq);
	}

	/**
	 * S-01首页（门店）分页查询
	 *
	 * @param page     分页
	 * @param homePageSearch 条件
	 * @return
	 */
	@Override
	public IPage<CnShopVo> getCmsShopPage(Page page, HomePageSearch homePageSearch) {
		IPage<CnShopVo> iPage = cnShopMapper.getCmsShopPage(page, homePageSearch);
		if (null != iPage.getRecords() && iPage.getRecords().size() > 0){
			iPage.getRecords().stream().forEach(o -> {
				List temp = cnCouShopMapper.selectList(Wrappers.lambdaQuery(CnCouShop.class).eq(CnCouShop::getShopId, o.getId()));
				o.setCouponCount(temp.size() + o.getTyCouponCount());
			});
		}
		return iPage;
	}
}
